#ifndef _STRAWGUI_COMPONENT_INSTANCE_H_
#define _STRAWGUI_COMPONENT_INSTANCE_H_

#include "sSaveable.h"
#include "sDrawContext.h"
#include "sDrawable.h"
#include "sNamedObject.h"
#include "sNamedObjectContainer.h"
#include "sComponentAlign.h"
#include "sControllerEvents.h"
#include <deque>

namespace sgui
{
namespace res
{
    class sComponent;
	class sComponentObject;
};
namespace inst
{

class sComponentRectInstance;
struct sActionHandlerEvent;

class sComponentInstance : public sNamedObject, public obs::sObserver
{
private:
	EControlState								m_state;
	std::deque<sComponentRectInstance*>			m_componentRects;
	std::deque<sComponentRectInstance*>			m_requiredRects;
	math::sRectf								m_rect;
    const res::sComponent&						m_component;
    const res::sComponentObject&				m_componentObject;
    CONTAINER_WRAPPER(sComponentInstance)		m_child;
	sComponentInstance*							m_parent;
	math::sPointf								m_offset;
private:
	void updateOffset();

	friend sGUI;
public:
	std::deque<sComponentRectInstance*>& getComponentRects() { return m_componentRects; }
	const std::deque<sComponentRectInstance*>& getComponentRects() const { return m_componentRects; }

	sComponentRectInstance* getComponentRect(u32 idx) { return m_componentRects[idx]; }
	const sComponentRectInstance* getComponentRect(u32 idx) const { return m_componentRects[idx]; }

	sComponentRectInstance* getRequiredComponentRect(u32 idx);
	const sComponentRectInstance* getRequiredComponentRect(u32 idx) const;

    const res::sComponent& getComponent();

	virtual void draw(engine::sDrawStack& drawStack) const;
	virtual void update(double dt);

	void setSize(math::sPointf newSize);
	void setPosition(math::sPointf newPosition);
	
	const math::sRectf& getRect() const { return m_rect; }
	const math::sPointf& getOffset() const { return m_offset; }
	sComponentRectInstance* getRectAt(const math::sPointf point);

	const sComponentInstance* getParent() const { return m_parent; }
	sComponentInstance* getParent() { return m_parent; }
	
	bool OnEvent(const obs::sEvent& event);
    virtual bool OnHandlerEvent(const sActionHandlerEvent& event);
    virtual bool OnPress(const obs::sMousePressEvent& event, sComponentRectInstance* rect);

	const EControlState& getState() const;
	virtual void setState(const EControlState& state);
	
	sComponentInstance(sGUI& gui, const res::sComponentObject& object, sComponentInstance* parent);
    virtual ~sComponentInstance();
};

};
};

#endif